﻿using System;
using __Able.Network.Packet;
using __Able.Network.Utils;

namespace CCU.Packet
{
    /// <summary>
    ///  [包头长度] |                         [包头]                         |  [包体]  |  [包尾]
    /// --------------------------------------------------------------------------------------------
    ///             |  [序号] | [包ID]   | [版本号] | [指令标记] | [模块名]  |          |   
    /// --------------------------------------------------------------------------------------------
    ///     ushort  |   byte  | byte[16] |  byte[4] |    ushort  |  byte[]   |   byte[] |   byte
    /// --------------------------------------------------------------------------------------------
    ///       2     |     1   |     16   |     4    |       2    |     n     |      n   |     1
    /// </summary>
    public abstract class CCUPacket : BasicPacket
    {
        /// <summary>
        /// 用户对象
        /// </summary>
        public User User { get; protected set; }
        /// <summary>
        /// 模块
        /// </summary>
        /// <value></value>
        public string Module { get; protected set; }
        /// <summary>
        /// 版本
        /// </summary>
        /// <value></value>
        public byte[] Version { get; protected set; }
        /// <summary>
        /// 指令标记
        /// </summary>
        /// <value></value>
        public ushort Token { get; protected set; }
        /// <summary>
        /// 包ID
        /// </summary>
        public byte[] ID { get; protected set; }
        /// <summary>
        /// 包序号
        /// </summary>
        /// <value></value>
        public byte Sequence { get; protected set; }
        /// <summary>
        /// 包创建时间
        /// </summary>
        /// <value></value>
        public DateTime DateTime { get; protected set; }
        /// <summary>
        /// 包尾
        /// </summary>
        public byte PacketTail { get; protected set; }

        /// <summary>
        /// 包的描述性名称
        /// </summary>
        public override string PacketName
        {
            get
            {
                return string.Format("{0}_{1}.{2}.{3}.{4}_{5}", Module, Version[0], Version[1], Version[2], Version[3], Token);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format("PacketName:\t{0}\nID:\t\t{1}\nSequence:\t{2}\nDateTime:\t{3}", PacketName, new Guid(ID).ToString(), Sequence, DateTime.ToString());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="module"></param>
        /// <param name="version"></param>
        /// <param name="token"></param>
        /// <param name="sequence"></param>
        /// <param name="id"></param>
        /// <param name="user"></param>
        public CCUPacket(string module, byte[] version, ushort token, byte sequence, byte[] id, User user, byte packetTail)
        {
            this.User = user;
            this.Module = module;
            this.Token = token;
            this.Version = version;
            this.Sequence = sequence;
            this.ID = id;
            this.DateTime = DateTime.Now;
            this.PacketTail = packetTail;

            _buf.Initialize();
            // 包头长度(占位)
            _buf.PutUShort(0);
            // 写入包头
            PutHead(_buf);
            // 回填包头长度
            _buf.PutUShort(0, (ushort)(_buf.Length - 2));
            // 写入包体
            PutBody(_buf);
            // 写入包尾
            PutTail(_buf);
        }

        public void Print()
        {
            _buf.Rewind();
            ParseHeader(_buf);
            ParseBody(_buf);
            ParseTail(_buf);
        }

        /// <summary>
        /// 将包头部转化为字节流, 写入指定的ByteBuffer对象.
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract void PutHead(ByteBuffer buf);
        /// <summary>
        /// 初始化包体
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract void PutBody(ByteBuffer buf);
        /// <summary>
        /// 初始化包尾
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract void PutTail(ByteBuffer buf);

        /// <summary>
        /// 从buf中解析包头
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract void ParseHeader(ByteBuffer buf);
        /// <summary>
        /// 从buf中解析包体
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract void ParseBody(ByteBuffer buf);
        /// <summary>
        /// 从buf中解析包尾
        /// </summary>
        /// <param name="buf"></param>
        protected abstract void ParseTail(ByteBuffer buf);
    }
}
